home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
101-125
/
disk_121
/
dataplot
/
data drawer
/
lsq
< prev
next >
Wrap
Text File
|
1992-05-06
|
5KB
|
178 lines
' "POLYNOMIAL CURVE FITTER"
' "FROM WILLIAM G. HOOD, BYTE, JUNE 1987"
' PRINT "MODIFIED BY DALE HOLT"
LN=1000 : LD=11 ' LN=MAX DATA POINTS; LD=HIGHEST DEGREE + 1
N=0: M=0: R2=0: MF=0
S1=0: S2=0: S3=0: S4=0: P1=0: P2=0
P3=0: I=0: J=0: J1=0: K=0
VR=0: MM=0: WT=0: P=0
DIM X(LN), Y(LN), W(LN), C(LD)
DIM D1(LD), D2(LD), D3(LD), D4(LD), D5(LD), D6(LD)
' GOSUB MATH 'CALLS THE SUBROUTINE
' INPUT:
' N=# OF DATA POINTS
' X( )=X-COORDINATES OF THE DATA POINTS
' Y( )=Y-COORDINATES OF THE DATA POINTS
' W( )=WEIGHTING FACTORS OF THE DATA POINTS
' M=DEGREE OF POLYNOMIAL
' MF=0 IF NEW DATA, MF=1 IF OLD DATA BUT HIGHER DEGREE
' OUTPUT:
' C=ARRAY OF M+1 COEFFICIENTS
' S2=RESIDUAL VARIANCE
' R2=COEFFICIENT OF DETERMINATION
START:
CLS
PRINT "POLYFIT. COPYRIGHT (C) 1986 BY WILLIAM G. HOOD"
PRINT "MODIFIED IN 1987 BY DALE HOLT"
PRINT
PRINT "THIS PROGRAM FINDS THE COEFFICIENTS OF THE NTH DEGREE POLY";
PRINT "NOMIAL"
PRINT
PRINT "Y = C(1)*X^N + C(2)*X^(N-1) + ... + C(N)*X + C(N+1)
PRINT
PRINT "THAT FITS A SET OF DATA POINTS IN A LEAST-SQUARES SENSE."
PRINT"EACH DATA POINT MUST CONSIST OF AN X-VALUE, A Y-VALUE, AND AN
PRINT"OPTIONAL WEIGHT, SEPARATED BY COMMAS AND TERMINATED BY A";
PRINT " RETURN."
PRINT "DATA IS READ FROM A DISK FILE UNTIL THE EOF IS REACHED, ";
PRINT "OR A"
PRINT "SPECIFIED NUMBER OF DATA POINTS ARE READ IN FROM THE ";
PRINT "KEYBOARD."
PRINT: PRINT "MODIFICATIONS BY DALE HOLT PERMIT SAVING A FILE";
PRINT " OF POINTS"
PRINT "GENERATED BY THE POLYNOMIAL WHICH HAS BEEN CALCULATED."
PRINT "THE ORIGINAL DATA POINTS CAN THEN BE PLOTTED ALONG WITH";
PRINT " THE CURVES"
PRINT "GENERATED BY THE LEAST SQUARES FIT FOR A VISUAL CHECK OF FIT
PRINT
INPUT "NAME OF THE DATA FILE (KYBD: = KEYBOARD)? ",FI$
INPUT "IS THE DATA WEIGHTED (Y/N)? ",W$
IF W$<>"Y" AND W$<>"y" THEN W$="N"
IF FI$<>"KYBD:" THEN L1190
L810:
PRINT "Keyboard data entry"
PRINT "How many data points (2 -";LN;")";: INPUT N
IF N=0 THEN N=LN
IF N<2 THEN PRINT "INVALID! ";: GOTO L810
FOR K=1 TO N
IF W$<>"N" THEN INPUT "X,Y,W? ",X(K),Y(K),W(K): W(K)=ABS(W(K))
IF W$="N" THEN INPUT "X,Y? ",X(K),Y(K): W(K)=1
NEXT K
L890:
PM=LD-1: IF N-1<PM THEN PM=N-1
L900:
PRINT "Degree of polynomial fit (1-";PM;")? ";
INPUT "",M : M=ABS(M)
IF M<1 OR M>PM THEN PRINT "INVALID! ";: GOTO L900
GOSUB MATH
PRINT: PRINT "Power Series Coefficients:"
FOR J=M+1 TO 1 STEP -1
PRINT " ";C(J);TAB(22);"X^";M+1-J
NEXT J
PRINT: PRINT "Residual variance: ";S2
PRINT: PRINT "Coefficient of Determination:";R2
L1010:
INPUT "Make a file of calculated points (Y/N)? ",A$
IF A$="" THEN A$="N"
A$=UCASE$(A$)
IF A$="N" THEN L1130
IF A$<>"Y" THEN PRINT "INVALID! ";: GOTO L1010
L1040:
INPUT "File name? ",F$
IF F$="" THEN PRINT "INVALID! ";: GOTO L1040
OPEN F$ FOR OUTPUT AS #5
FOR I=1 TO N: P=C(1)
FOR K=1 TO M
P=P*X(I)+C(K+1)
NEXT K
' PRINT X(I);",";P ' PRINT TO SCREEN ALSO
PRINT #5, X(I);",";P
NEXT I
CLOSE 5
L1130:
INPUT "Try another degree? ",A$
IF A$="" THEN A$="N"
A$=UCASE$(A$)
IF A$="N" THEN END
IF A$="Y" THEN GOTO L900
PRINT "INVALID! ";: GOTO L1130
L1190:
PRINT "Reading from file: ";FI$
OPEN FI$ FOR INPUT AS #1
N=0
PRINT "X";TAB(15);"Y";TAB(28);"W";:PRINT
WHILE NOT EOF(1)
N=N+1
IF W$<>"N" THEN INPUT #1,X(N),Y(N),W(N): W(N)=ABS(W(N))
IF W$="N" THEN INPUT #1,X(N),Y(N): W(N)=1
PRINT X(N);TAB(14);Y(N);TAB(28);W(N)
WEND
CLOSE 1
PRINT: PRINT N;" points were read from the file."
GOTO L890
GOTO START
' CALCULATION SUBROUTINE
MATH:
IF MF>0 AND M>MM THEN J1=MM+1: MM=M: GOTO L200
J1=1: MM=M: S1=0: S2=0: S3=0: S4=0
FOR I=1 TO N
WT=W(I)
S1=S1+WT*X(I): S2=S2+WT: S3=S3+WT*Y(I): S4=S4+WT*Y(I)*Y(I)
NEXT I
D4(1)=S1/S2: D5(1)=0: D6(1)=S3/S2: D1(1)=0: D2(1)=1
VR=S4-S3*D6(1)
L200:
FOR J=J1 TO MM
S1=0: S2=0: S3=0: S4=0
FOR I=1 TO N
P1=0: P2=1
FOR K=1 TO J
P=P2: P2=(X(I)-D4(K))*P2-D5(K)*P1: P1=P
NEXT K
WT=W(I): P=WT*P2*P2
S1=S1+P*X(I): S2=S2+P: S3=S3+WT*P1*P1: S4=S4+WT*Y(I)*P2
NEXT I
D4(J+1)=S1/S2: D5(J+1)=S2/S3: D6(J+1)=S4/S2
D3(1)=-D4(J)*D2(1)-D5(J)*D1(1)
IF J=>4 THEN
FOR K=2 TO J-2
D3(K)=D2(K-1)-D4(J)*D2(K)-D5(J)*D1(K)
NEXT K
END IF
IF J>2 THEN D3(J-1)=D2(J-2)-D4(J)*D2(J-1)-D5(J)
IF J>1 THEN D3(J)=D2(J-1)-D4(J)
FOR K=1 TO J
D1(K)=D2(K): D2(K)=D3(K): D6(K)=D6(K)+D3(K)*D6(J+1)
NEXT K
NEXT J
FOR J=1 TO M+1
C(J)=D6(M+2-J)
NEXT J
P2=0
FOR I=1 TO N
P=C(1)
FOR J=1 TO M
P=P*X(I)+C(J+1)
NEXT J
P=P-Y(I): P(2)=P2+W(I)*P*P
NEXT I
S2=0: IF N>M+1 THEN S2=P2/(N-M-1)
R2=1: IF VR<>0 THEN R2=1-P2/VR: IF R2<0 THEN R2=0
RETURN
END